package com.andrewchatham.pony;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.util.Log;

class HTTPRequest {
	static public String TAG = "HTTP";
	private URL mUrl;
	private boolean mSuccess;
	private boolean mPreserveResponse;
	private OutputStream mOutput;
	private ProgressHandler mProgress;
	
	interface ProgressHandler {
	  public void setProgress(int max, int progress);
	}

	public HTTPRequest(String url) {
		Init(url, new ByteArrayOutputStream());
		mPreserveResponse = true;
	}

	public HTTPRequest(String url, OutputStream output) {
		Init(url, output);
		mPreserveResponse = false;
	}
	
	public void setProgressHandler(ProgressHandler progress) {
	  mProgress = progress;
	}

	private void Init(String url, OutputStream output) {
		try {
			mUrl = new URL(url);
		} catch (MalformedURLException e) {
			Log.d(TAG, "Bad URL " + url);
		}
		mOutput = output;
	}

	boolean success() {
		return mSuccess;
	}

	byte[] response() {
		if (mPreserveResponse)
			return ((ByteArrayOutputStream) mOutput).toByteArray();
		else
			return null;
	}

	void run() {
		if (mUrl == null) return;
		try {
			HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection();
			connection.setConnectTimeout(10000);
			connection.setReadTimeout(30000);
			connection.connect();
			InputStream is = connection.getInputStream();
			int length = connection.getContentLength();
			int bytesRead;
			byte[] buffer = new byte[1<<15];
			int count = 0;
			while ((bytesRead = is.read(buffer)) != -1) {
				mOutput.write(buffer, 0, bytesRead);
				count += bytesRead;
				if (length != -1 && mProgress != null)
				  mProgress.setProgress(length, count);
			}

			mOutput.flush();
			mOutput.close();
			is.close();
			Log.d(TAG, String.format("finished request(size=%d, remote=%s code=%s)",
					count, mUrl.toString(), connection.getResponseMessage()));
			mSuccess = connection.getResponseCode() == 200;
		} catch (IOException e) {
			Log.d(TAG, "Done " + e.toString());
			mSuccess = false;
		}
	}
}

class AsyncHTTPRequest extends Thread {
	static final String TAG = "AsyncHttpRequest";
	final private Handler mHandler;
	final private HTTPRequest mReq;

	interface Handler {
		public void HandleResponse(boolean success, byte[] bs);
	}

	public AsyncHTTPRequest(String url, Handler handler) {
		mReq = new HTTPRequest(url);
		mHandler = handler;
		Log.d(TAG, String.format("started request(remote=%s)", url));
		start();
	}

	public void run() {
		Log.d(TAG, "Get thread started");
		mReq.run();
		mHandler.HandleResponse(mReq.success(), mReq.response());
	}
}
